import math

from django.http import JsonResponse
from rest_framework.views import APIView
from rest_framework.pagination import PageNumberPagination  # rest_framework分页模块
from rest_framework import serializers   # rest_framework序列化模块
from rest_framework.response import Response
from dal import models
import numpy as np


# 序列化设置
class PagerSerialiser(serializers.ModelSerializer):

    time = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S')

    class Meta:
        model = models.History
        fields = "__all__"



def make(data, n):
    # 二值化处理 n为长度
    rea_data = np.zeros(n+1, dtype=np.int)
    # 将所选号码填充为1
    rea_data[data] = 1
    return rea_data

def calculation(mine,other):
    fenzi = 0
    for x in range(len(mine)):
        fenzi = fenzi +  mine[x] * other[x]
    fenmu1 = 0
    for x in range(len(mine)):
        fenmu1 = fenmu1 +  mine[x] * mine[x]
    fenmu1 = math.sqrt(fenmu1)
    fenmu2 = 0
    for x in range(len(other)):
        fenmu2 = fenmu2 + other[x] * other[x]
    # 计算权重
    fenmu2 = math.sqrt(fenmu2)
    cos_th = fenzi / (fenmu1*fenmu2)
    return cos_th


class Recommend(APIView):

    authentication_classes = []

    def get(self, request):

        data = {}

        try:
            try:
                user_id_ds = models.UserInfo.objects.get().pk
                user_look_list = []
                user_look_obj = models.Look.objects.filter(user_id=user_id_ds).values("news_id")
                for good_id in user_look_obj:
                    user_look_list.append(good_id.get("news_id"))
                # 创建排序组
                sort_user_pk_list = []
                # 其他用户的浏览数组
                look_list_all = []
                user_all = models.UserInfo.objects.values("pk").all()
                for user_obj in user_all:
                    if user_obj.get("pk") != user_id_ds:
                        sort_user_pk_list.append(user_obj.get("pk"))
                        look_list_obj_other = models.Look.objects.filter(user_id=user_obj.get("pk")).values(
                            "news_id")
                        other_look_list = []
                        for look_id in look_list_obj_other:
                            other_look_list.append(look_id.get("news_id"))
                        look_list_all.append(other_look_list)

                good_count = models.Look.objects.all().order_by("-id").values("pk")
                # 计算二值化
                user_binaryzation_list = make(user_look_list, int(good_count[0].get("pk")))
                # 计算最推荐值
                list_res = []
                for data in look_list_all:
                    list_res.append(calculation(user_binaryzation_list, make(data, int(good_count[0].get("pk")))))
                max_index = list_res.index(max(list_res))
                # 筛选出最匹配
                res_user_id = sort_user_pk_list[max_index]
                data_list = models.Look.objects.filter(user_id=res_user_id).values("good_id")[0:5]
            except:
                data_list = models.History.objects.order_by('?')[0:5]


            pg = PageNumberPagination()
            pg.max_page_size = 200
            pg.page_size_query_param = "size"
            # 在数据库中获取分页的数据
            pager_roles = pg.paginate_queryset(queryset=data_list, request=request, view=self)
            # 对分页数据进行序列化
            ser = PagerSerialiser(instance=pager_roles, many=True)
            data["code"] = 200
            data["data"] = ser.data
            return Response(data)
        except Exception as e:
            print(e)
            data["code"] = 444
            data["message"] = "请求异常"
            return JsonResponse(data)